package com.personal.gateway.flinkAllCommand.configurationOption.webObjectGenerator;

import com.personal.gateway.flinkAllCommand.configurationOption.ConfigurationOption;
import com.personal.gateway.flinkAllCommand.configurationOption.configurationType.AbstractConfigurationType;
import com.personal.gateway.utils.StringTemplateUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @author BigHead
 * @date 2022/1/10 15:45
 * @description AbstractWebObjectGenerator
 */
public abstract class AbstractWebObjectGenerator<BT, CT extends AbstractConfigurationType<BT>> {

    private static final Map<String, String> RECODE_DECODE_STRING_MAP = new HashMap<String, String>() {{
        put(".", "0_000");
        put("/", "0_001");
    }};

    private static final String NECESSARY_ELEMENT_CLASS = "<span class=\"layui-badge-dot\"></span>";

    protected static final String ERROR_MARK = "ERROR_MARK";
    protected static final String ERROR_MARK_CLASS = " layui-bg-red";


    // 具体输入选项框

    protected static final String GROUP_ELEMENT = "GROUP_ELEMENT";
    protected static final String LABEL_ID = "LABEL_ID";
    protected static final String WEB_SHOW_NAME = "WEB_SHOW_NAME";
    protected static final String NECESSARY_ELEMENT = "NECESSARY_ELEMENT";
    protected static final String INPUT_ELEMENT = "INPUT_ELEMENT";
    protected static final String DESCRIBE_ELEMENT = "DESCRIBE_ELEMENT";
    protected static final String WEB_ELEMENT_TEMPLATE = "" +
            "${GROUP_ELEMENT}" +
            "<div class=\"layui-form-item\" style=\"white-space:nowrap;\">\n" +
            "<label id=\"${LABEL_ID}\" class=\"layui-form-label${ERROR_MARK}\" ${INFOMATION_ELEMENT}>${WEB_SHOW_NAME}${NECESSARY_ELEMENT}</label>\n" +
            "<div class=\"layui-input-block\" style=\"margin-left: 120px; margin-right: 5%\">\n" +
            "${INPUT_ELEMENT}\n" +
            "</div>\n" +
            "${DESCRIBE_ELEMENT}" +
            "</div>\n";
    // TODO 这里汉字不要超过7个 否则会跑到其他控件下

    // 类别分组

    protected static final String GROUP_NAME = "GROUP_NAME";
    protected static final String GROUP_ELEMENT_TEMPLATE = "" +
            "<div class=\"site-title\">\n" +
            "<fieldset><legend><a>${GROUP_NAME}</a></legend></fieldset>\n" +
            "</div>";

    // 描述信息

    protected static final String DESCRIBE_ID = "DESCRIBE_ID";
    protected static final String DESCRIBE_ELEMENT_TEMPLATE = "" +
            "<div style=\"float: right;top: -30px;height: 0;position: relative;\">\n" +
            "<i id=\"${DESCRIBE_ID}\" ${INFOMATION_ELEMENT} class=\"layui-icon layui-icon-tips\" style=\"font-size: 20px; color: #1E9FFF;\"></i>\n" +
            "</div>\n";

    // 鼠标移动悬停

    protected static final String INFOMATION_ELEMENT = "INFOMATION_ELEMENT";
    protected static final String INFOMATION_ID = "INFOMATION_ID";
    protected static final String INFOMATION_STRING = "INFOMATION_STRING";
    protected static final String INFOMATION_ELEMENT_FUNCTION_TEMPLATE = "onmouseover='parameterDescribe(\"${INFOMATION_STRING}\", \"#${INFOMATION_ID}\")'";

    /**
     * 拼接页面汇总
     *
     * @param configurationOption 参数信息
     * @param isFirst             是否为参数组第一位
     * @return 页面元素汇总
     */
    public String getWebElement(ConfigurationOption<BT, CT> configurationOption, boolean isFirst) {
        if (
                null != configurationOption.getAntecedentConfigurationOption() &&
                        null != configurationOption.getAntecedentConfigurationOption().getConfigurationType().getValue()
        ) {
            return getWebElementFunction(configurationOption, isFirst);
        }
        if (null == configurationOption.getAntecedentConfigurationOption()) {
            return getWebElementFunction(configurationOption, isFirst);
        }
        return "";
    }

    /**
     * 页面共有生成方式
     *
     * @param configurationOption 参数信息
     * @param isFirst             是否为参数组第一位
     * @return 页面元素汇总
     */
    private String getWebElementFunction(ConfigurationOption<BT, CT> configurationOption, boolean isFirst) {
        String groupElement = getGroupElement(configurationOption, isFirst);
        String inputElement = getInputElement(configurationOption);
        String describeElement = getDescribeElement(configurationOption);
        return StringTemplateUtils.render(
                WEB_ELEMENT_TEMPLATE,
                new HashMap<String, String>(4) {{
                    put(GROUP_ELEMENT, groupElement);
                    put(LABEL_ID, webElementIdRecode(configurationOption.getConfigurationKey().getName()));
                    put(ERROR_MARK, null == configurationOption.getConfigurationOptionCheckException() ?
                            "" :
                            ERROR_MARK_CLASS
                    );
                    put(INFOMATION_ELEMENT, null == configurationOption.getConfigurationOptionCheckException() ?
                            "" :
                            getInfomationFunction(configurationOption.getConfigurationOptionCheckException().getMessage(), webElementIdRecode(configurationOption.getConfigurationKey().getName()))
                    );
                    put(NECESSARY_ELEMENT, configurationOption.isNecessary() ? NECESSARY_ELEMENT_CLASS : "");
                    put(WEB_SHOW_NAME, configurationOption.getWebShowName());
                    put(INPUT_ELEMENT, inputElement);
                    put(DESCRIBE_ELEMENT, describeElement);
                }}
        );
    }

    /**
     * 拼接数据分组
     *
     * @param configurationOption 参数信息
     * @return 分区元素
     */
    protected String getGroupElement(ConfigurationOption<BT, CT> configurationOption, boolean isFirst) {
        if (isFirst) {
            return StringTemplateUtils.render(
                    GROUP_ELEMENT_TEMPLATE,
                    new HashMap<String, String>(1) {{
                        put(GROUP_NAME, configurationOption.getGroupKey().getName());
                    }}
            );
        }
        return "";
    }

    /**
     * 页面数据输入框
     *
     * @param configurationOption 参数信息
     * @return 页面数据输入元素
     */
    protected abstract String getInputElement(ConfigurationOption<BT, CT> configurationOption);


    /**
     * 页面输入框的描述ICON
     *
     * @param configurationOption 参数信息
     * @return 页面描述元素
     */
    protected String getDescribeElement(ConfigurationOption<BT, CT> configurationOption) {
        return StringTemplateUtils.render(
                DESCRIBE_ELEMENT_TEMPLATE,
                new HashMap<String, String>(2) {{
                    put(DESCRIBE_ID, webElementIdRecode(configurationOption.getConfigurationKey().getName()) + "_describe");
                    put(INFOMATION_ELEMENT, getInfomationFunction(configurationOption.getDescribe(), webElementIdRecode(configurationOption.getConfigurationKey().getName()) + "_describe"));
                }}

        );
    }

    /**
     * 统一返回鼠标移入 函数
     *
     * @param infomationString 消息信息
     * @param infomationId     消息信息ID
     * @return 返回页面消息信息函数
     */
    protected String getInfomationFunction(String infomationString, String infomationId) {
        return StringTemplateUtils.render(
                INFOMATION_ELEMENT_FUNCTION_TEMPLATE,
                new HashMap<String, String>(2) {{
                    put(INFOMATION_ID, infomationId);
                    put(INFOMATION_STRING, infomationString);
                }}
        );
    }

    /**
     * 通过替换. 来使前端页面ID不出现异常
     *
     * @param originalString 原始ID字符串
     * @return 替换.后的字符串
     */
    public static String webElementIdRecode(String originalString) {
        for (Map.Entry<String, String> mapEntry : RECODE_DECODE_STRING_MAP.entrySet()) {
            originalString = originalString.replace(mapEntry.getKey(), mapEntry.getValue());
        }
        return originalString;
    }

    /**
     * 通过页面传回的字段ID 来完成对应Key的转换
     *
     * @param webIdString 页面ID的字符串
     * @return 返回特定Key
     */
    public static String webElementIdDecode(String webIdString) {
        for (Map.Entry<String, String> mapEntry : RECODE_DECODE_STRING_MAP.entrySet()) {
            webIdString = webIdString.replace(mapEntry.getValue(), mapEntry.getKey());
        }
        return webIdString;
    }
}
